package uk.ac.ebi.pride.peptidome;

import org.apache.log4j.Logger;
import uk.ac.ebi.pride.jaxb.model.ModificationItem;
import uk.ac.ebi.pride.tools.mgf_parser.MgfFile;
import uk.ac.ebi.pride.tools.peak_list_parser.PeakListParserException;

import java.io.File;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by IntelliJ IDEA.
 * User: rwang
 * Date: 20/05/11
 * Time: 10:46
 */
public class PeptidomeConverter {
    private static final Logger logger = Logger.getLogger(PeptidomeConverter.class);

    private final File[] metaDataFiles;
    private final String spectrumFolder;
    private final String outputFolder;

    public PeptidomeConverter(String metaDataFolder, String spectrumFolder, String outputFolder) {
        this.metaDataFiles = new File(metaDataFolder).listFiles();
        this.spectrumFolder = spectrumFolder;
        this.outputFolder = outputFolder;
    }

    public void convert() {
        // get unimod ptms
        Map<String, ModificationItem> ptms = new UnimodReader().parse();

        // get pride mappings
        Map<String, Map<String, String>> mappings = new PrideMappingReader().parse();

        // parse each meta data files
        for (File metaDataFile : metaDataFiles) {
            logger.info("Reading Peptidome Meta Data: " + metaDataFile.getName());
            PeptidomeReader reader = new PeptidomeReader(metaDataFile);
            String study = reader.getStudyAccession();
            List<String> accessions = reader.getSampleAccessions();
            for (String accession : accessions) {
                Map<String, String> accs = mappings.get(study);
                if (accs != null) {
                    String prideAccession = accs.get(accession.replace("PSM", ""));
                    if (prideAccession != null) {
                        convertSample(reader, ptms, accession, prideAccession);
                    }
                }
            }
        }
    }

    /**
     * Convert each individual sample
     *
     * @param sampleAcc sample accession
     */
    private void convertSample(PeptidomeReader reader, Map<String, ModificationItem> ptms, String sampleAcc, String prideAcc) {
        // get mgf files parsers
        Map<String, MgfFile> mgfReaders = new LinkedHashMap<String, MgfFile>();
        String fileSep = System.getProperty("file.separator");
        String mgfFolder = spectrumFolder + (outputFolder.endsWith(fileSep) ? "" : fileSep) + sampleAcc;
        logger.info("Reading MGF folder: " + mgfFolder);
        File[] mgfFiles = new File(mgfFolder).listFiles();
        for (File mgfFile : mgfFiles) {
            String fileName = mgfFile.getName();
            logger.info("Reading MGF file: " + fileName);
            String formattedFileName = fileName.replace(".mgf", "").replace(sampleAcc + "_", "");
            // mgf reader
            MgfFile mgfReader = null;
            try {
                mgfReader = new MgfFile(mgfFile);
            } catch (PeakListParserException e) {
                logger.error("Failed to create mgf file reader", e);
            }
            mgfReaders.put(formattedFileName, mgfReader);
            logger.info("Used memory: " + (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()));
        }

        // get output file name
        String outputFileName = outputFolder + (outputFolder.endsWith(fileSep) ? "" : fileSep) + sampleAcc + ".xml";
        logger.info("Output Pride Xml: " + outputFileName);

        // create interpreter
        PeptidomeToPrideInterpreter interpreter = new PeptidomeToPrideInterpreter(reader, sampleAcc, ptms);
        logger.info("PeptidomeToPrideInterpreter is created");

        // create writer
        PeptidomePrideXmlWriter writer = new PeptidomePrideXmlWriter(interpreter, reader, sampleAcc, mgfReaders, outputFileName, prideAcc);

        try {
            writer.writerXml();
        } catch (ConverterException e) {
            logger.error("Converter Exception", e);
        }
    }

    public static void main(String[] args) {
        if (args.length != 3) {
            throw new IllegalArgumentException("Error Input Arguments: java PeptidomeConverter [peptidome metadata folder] [peptidome spectrum folder] [pride xml output folder]");
        }

        PeptidomeConverter converter = new PeptidomeConverter(args[0], args[1], args[2]);
        converter.convert();
    }
}
